package tail

import (
	"context"
	"github.com/hpcloud/tail"
	"log/lg"
	"log/nsq"
)

// TailTask 构造tail结构体
type TailTask struct {
	path     string     //采集日志路径
	topic    string     //跟路径对应的 消息队列主题
	instance *tail.Tail //实例对象
	//为了实现退出t.run的后台
	ctx        context.Context
	cancelFunc context.CancelFunc
}

// NewTailTask 初始化构造函数
func NewTailTask(path, topic string) (tailObj *TailTask) {
	ctx, cancel := context.WithCancel(context.Background())
	tailObj = &TailTask{
		path:       path,  //传入路径
		topic:      topic, //传入主题
		ctx:        ctx,
		cancelFunc: cancel,
	}
	tailObj.init() //构造函数的时候直接创建
	return
}

func (t *TailTask) init() {
	config := tail.Config{
		ReOpen:    true,                                 // 重新打开
		Follow:    true,                                 // 是否跟随
		Location:  &tail.SeekInfo{Offset: 0, Whence: 2}, // 从文件的哪个地方开始读
		MustExist: false,                                // 文件不存在不报错
		Poll:      true,
	}
	var err error
	//打开文件,创建对象
	t.instance, err = tail.TailFile(t.path, config)
	if err != nil {
		lg.Log.Info("打开文件创建文件对象错误:", err)
	}

	go t.run() //收集到的日志直接发送到nsq
}

//运行的方法
func (t *TailTask) run() {
	for {
		select {
		case <-t.ctx.Done():
			lg.Log.Info("退出一个tail实例:", t.path, "_", t.topic)
			return
		case line := <-t.instance.Lines:
			//采集的日志发送到nsq
			//异步发送到nsq中
			//把采集的日志发送到nsq的通道中
			nsq.SendChan(line.Text, t.topic)
		}
	}
}
